<?php

namespace App\Http\Controllers;

use App\Http\Models\Record;
use App\Http\Models\Task;
use App\Http\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class FriendController extends Controller
{

    public function __construct()
    {
        //
    }

    public function getFriendList(Request $req)
    {
        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if (!isset($uinfo['duckId'])) return $this->throwError('ErrFriendDataError');

        $friend_list = \App\Http\Models\User::myFriends($uid);

        $friend_list[] = [
            'uid' => $uid,
            'duckId' => $uinfo['duckId'],
            'nickName' => $uinfo['nickName'],
            'avatar' => $uinfo['avatar'],
            'usedStar' => $uinfo['totalStar'],
        ];

        return $this->result($friend_list);
    }

    public function visitFriend(Request $req)
    {
        $fuid = $req->input('uid');
        if (!$fuid) return $this->throwError('ErrClientParams');

        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        if ($fuid == $uid) return $this->throwError('ErrClientParams');

        $has_friend = false;
        $friend_list = \App\Http\Models\User::myFriends($uid);
        foreach ($friend_list as $f) {
            if ($f['uid'] == $fuid) {
                $has_friend = true;
                break;
            }
        }
        if (!$has_friend) return $this->throwError('ErrNoThisFriend');

        $finfo = DB::table('users')->where('id', $fuid)->first();
        if (!isset($finfo['duckId'])) return $this->throwError('ErrFriendDataError');
        $finfo['uid'] = $finfo['id'];

        $duck_info = DB::table('ducks')->where('id', $finfo['duckId'])->first();
        if (!isset($duck_info['id'])) return $this->throwError('ErrFriendDataError');

        // 刷新好友鸭子数据
        User::refreshFodder($fuid, $duck_info, true);

        // 完成拜访任务
        Task::setProgress($uid, config('game.cfg.TaskIDFriendFeed'), 1);

        return $this->result([
            'user' => $finfo,
            'duck' => $duck_info,
            'dropAround' => User::getDropRound($fuid),
        ]);
    }

    public function feedFriend(Request $req)
    {
        $is_seed = $req->input('seed') ?? false;
        $fuid = $req->input('uid');
        if (!$fuid) return $this->throwError('ErrClientParams');

        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        if ($fuid == $uid) return $this->throwError('ErrClientParams');

        $has_friend = false;
        $friend_list = \App\Http\Models\User::myFriends($uid);
        foreach ($friend_list as $f) {
            if ($f['uid'] == $fuid) {
                $has_friend = true;
                break;
            }
        }
        if (!$has_friend) return $this->throwError('ErrNoThisFriend');

        // 好友喂食限制
        if(Redis::SISMEMBER('FriendFeed:'.date('Ymd').':'.$fuid, $uid)) {
            return $this->throwError('ErrAlreadyFeed');
        }

        $finfo = DB::table('users')->where('id', $fuid)->first();
        if (!isset($finfo['duckId'])) return $this->throwError('ErrFriendDataError');

        $duck_info = DB::table('ducks')->where('id', $finfo['duckId'])->first();
        if (!isset($duck_info['id'])) return $this->throwError('ErrFriendDataError');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $need_fodder = config('game.cfg.FriendFeedConsume');
        if($uinfo['fodder'] < $need_fodder) return $this->throwError('ErrNotEnoughFodder');

        // $now = self::now();
        // 刷新好友鸭子数据
        User::refreshFodder($fuid, $duck_info, false);

        // 不在家喂个毛
        if($duck_info['status'] == config('game.cfg.DuckStatus.Steal')) return $this->throwError('ErrFriendDuckNotHome');
        // 没吃完喂个毛
        if($duck_info['leftFodder'] > 0 && $duck_info['lastFeedTime'] > 0) return $this->throwError('ErrFeedColdTime2');

        $now = time();
        $duck_info['leftFodder'] = $need_fodder;
        $duck_info['startFeedTime'] = $now;
        $duck_info['updateFeedTime'] = $now;
        $duck_info['lastFeedTime'] = config('game.cfg.BasePerDigestionTime');

        DB::beginTransaction();
        try {
            // 消耗自己的饲料
            DB::table('users')->where('id', $uid)->decrement('fodder', $need_fodder);
            file_put_contents('/tmp/fodder_change.log', date('Y-m-d').' ===== '.'  uid:'.$uid.' from:friend_feed  change:-'.$need_fodder.'  before:'.$uinfo['fodder'].'  after:'.($uinfo['fodder']-$need_fodder)."\n", FILE_APPEND);
            DB::table('ducks')->where('id', $duck_info['id'])->update([
                'feedCount' => $duck_info['feedCount'],
                'leftFodder' => $duck_info['leftFodder'],
                'startFeedTime' => $duck_info['startFeedTime'],
                'updateFeedTime' => $duck_info['updateFeedTime'],
                'waitGainStar' => $duck_info['waitGainStar'],
                'lastFeedTime' => $duck_info['lastFeedTime'],
            ]);
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->throwError('ErrFeedDbOperate', $e->getMessage());
        }
        DB::commit();

        // 好友喂食任务
        Task::setProgress($fuid, config('game.cfg.TaskIDFriendFeed'), 1);
        // 好友喂食记录
        Record::new($fuid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordFeedFriend'), [$uinfo['nickName'], $need_fodder]);

        // 添加投喂记录-显示用
        Record::byFeedRecord($fuid, $uid, $uinfo['nickName'], $uinfo['avatar']);

        // 增加今日已喂食限制
        $is_exists = false;
        if( Redis::EXISTS('FriendFeed:'.date('Ymd').':'.$fuid) ) {
            $is_exists = true;
        }
        Redis::SADD('FriendFeed:'.date('Ymd').':'.$fuid, $uid);
        if(!$is_exists) {
            Redis::EXPIRE('FriendFeed:'.date('Ymd').':'.$fuid, 86400);
        }

        // 给来伊份app发消息
        if($is_seed) {
            $step1 = microtime(true);
            file_put_contents('/tmp/login_record.log', "start get seed message ...\n", FILE_APPEND);
            $just_url = '/duckery/web/game/index.html';
            $pstr = json_encode([
                'lyfuid' => $finfo['openid'],
                'messageDetaiUrl' => env('LOCAL_API') . $just_url, // 消息点击跳转url 非必需
                'messageImageUrl' => 'https://www.bkdau.cn/damai/lyfen/bannerUpload/icon_20201124202535_850990.png', // 消息图片url
                'messageInfo' => '你的鸭鸭肚子饿扁了，有好心人帮你喂了，快去看看吧', // 消息内容
                'messageOrigin' => '来养鸭', // 消息的来源,如来养鸭
                'messageTitle' => '你的好友投喂了你的小鸭', // 消息标题
                'messageType' => '100', // 消息类型，固定值：100
            ]);
            $uri = '/supplier-app-api/v1/supplier/notify';
            $url = env('ORIGIN_API') . $uri;
            $sig_time = \App\Http\Controllers\Controller::now();
            $sig = base64_encode(hash_hmac(
                "sha1",
                "POST\n" .
                $uri . "\n" .
                "x-co-client:" . env('APPID') . "\n" .
                "x-co-timestamp:" . $sig_time . "\n" .
                strtoupper(md5($pstr)),
                env('APPSECRET'),
                true
            ));
            $headers = [
                'Content-Type:application/json',
            ];
            $headers[] = 'X-Co-Client:' . env('APPID');
            $headers[] = 'X-Co-TimeStamp:' . $sig_time;
            $headers[] = 'X-Co-Sign:' . $sig;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $pstr);
            $output = curl_exec($ch);
            curl_close($ch);
            $login_result = json_decode($output, true);

            $step2 = microtime(true);
            file_put_contents('/tmp/login_record.log', "get seed message: ".$output."    spend time: ".round($step2-$step1, 5)."\n", FILE_APPEND);

            if (!isset($login_result['code']) || $login_result['code'] != '0') {
                file_put_contents('/tmp/login_error.log', date('Y-m-d H:i:s')."==========================================\n".$uinfo['openid']."\n".$output."\n\n", FILE_APPEND);
                // return isset($login_result['msg']) ? $this->error($login_result['msg']) : $this->error(json_encode($login_result));
            }
        }

        return $this->result([
            'duck' => $duck_info,
            'fodder' => $uinfo['fodder'] - $need_fodder,
            'usedSelf' => true,
        ]);
    }


    /**
     * 好友投喂记录
     *
     * @param Request $req
     * @return void
     */
    public function byFeed(Request $req)
    {
        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        $records = Record::byFeedRecords($uid);
        if(!empty($records)) {
            // 排序
            $sort = [];
            foreach($records as $record) {
                $record_data = json_decode($record, true);
                $sort[] = $record_data['time'];
            }
            array_multisort($sort, SORT_DESC, SORT_NUMERIC, $records);
        }

        return $this->result([
            'record_list' => $records,
        ]);
    }

    /**
     * 好友助力
     *
     * @param Request $req
     * @return void
     */
    public function helpFriend(Request $req)
    {
        $fuid = $req->input('uid');
        if (!$fuid) return $this->throwError('ErrClientParams');

        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        if ($fuid == $uid) return $this->throwError('ErrClientParams');

        $has_friend = false;
        $friend_list = \App\Http\Models\User::myFriends($uid);
        foreach ($friend_list as $f) {
            if ($f['uid'] == $fuid) {
                $has_friend = true;
                break;
            }
        }
        if (!$has_friend) return $this->throwError('ErrNoThisFriend');

        // 助力每日限制
        if(Redis::SISMEMBER('FriendHelp:'.date('Ymd').':'.$fuid, $uid)) {
            return $this->throwError('ErrAlreadyHelp');
        }
        if(Redis::SCARD('FriendHelp:'.date('Ymd').':'.$fuid) >= config('game.cfg.FriendHelpMaxTimes') ) {
            return $this->throwError('ErrMaxHelp');
        }

        $finfo = DB::table('users')->where('id', $fuid)->first();
        if (!isset($finfo['duckId'])) return $this->throwError('ErrFriendDataError');

        $duck_info = DB::table('ducks')->where('id', $finfo['duckId'])->first();
        if (!isset($duck_info['id'])) return $this->throwError('ErrFriendDataError');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        // 刷新好友鸭子数据
        User::refreshFodder($fuid, $duck_info, false);

        // 不在家不可助力
        if($duck_info['status'] == config('game.cfg.DuckStatus.Steal')) return $this->throwError('ErrFriendDuckNotHome2');
        // 已吃完, 不可助力
        if($duck_info['leftFodder'] <= 0 && $duck_info['lastFeedTime'] <= 0) return $this->throwError('ErrFriendHelpNoFeed');

        $duck_info['startFeedTime'] -= config('game.cfg.FriendHelpIntervalTime');
        $duck_info['updateFeedTime'] -= config('game.cfg.FriendHelpIntervalTime');
        $duck_info['lastFeedTime'] -= config('game.cfg.FriendHelpIntervalTime');

        // 刷新好友鸭子数据
        User::refreshFodder($fuid, $duck_info, false);

        $add_fodder = config('game.cfg.FriendHelpGetFeed');
        DB::beginTransaction();
        try {
            file_put_contents('/tmp/fodder_change.log', date('Y-m-d').' ===== '.'  uid:'.$uid.' from:friend_help  change:-'. config('game.cfg.FriendHelpIntervalTime')
              .'  before:'.$duck_info['startFeedTime'].'  after:'.($duck_info['startFeedTime']+config('game.cfg.FriendHelpIntervalTime'))."\n", FILE_APPEND);

            DB::table('ducks')->where('id', $duck_info['id'])->update([
                'feedCount' => $duck_info['feedCount'],
                'leftFodder' => $duck_info['leftFodder'],
                'startFeedTime' => $duck_info['startFeedTime'],
                'updateFeedTime' => $duck_info['updateFeedTime'],
                'waitGainStar' => $duck_info['waitGainStar'],
                'lastFeedTime' => $duck_info['lastFeedTime'],
            ]);
            // 给助力的朋友加饲料
            DB::table('users')->where('id', $uid)->increment('fodder', $add_fodder);
            file_put_contents('/tmp/fodder_change.log', date('Y-m-d').' ===== '.'  uid:'.$uid.' from:friend_help  change:'.$add_fodder.'  before:'.$uinfo['fodder'].'  after:'.($uinfo['fodder']+$add_fodder)."\n", FILE_APPEND);

        } catch(\Exception $e) {
            DB::rollBack();
            return $this->throwError('ErrFeedDbOperate', $e->getMessage());
        }
        DB::commit();

        // 增加今日已助力限制
        $is_exists = false;
        if( Redis::EXISTS('FriendHelp:'.date('Ymd').':'.$fuid) ) {
            $is_exists = true;
        }
        Redis::SADD('FriendHelp:'.date('Ymd').':'.$fuid, $uid);
        if(!$is_exists) {
            Redis::EXPIRE('FriendHelp:'.date('Ymd').':'.$fuid, 86400);
        }

        // 好友助力记录
        Record::new($fuid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordHelpFriend'), [$uinfo['nickName']]);

        return $this->result([
            'duck' => $duck_info,
            'add_fodder' => $add_fodder,
        ]);
    }

    /**
     * 好友是否可以助力
     *
     * @param Request $req
     * @return void
     */
    public function isHelpFriend(Request $req)
    {
        $fuid = $req->input('uid');
        if (!$fuid) return $this->throwError('ErrClientParams');
        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');
        if ($fuid == $uid) return $this->throwError('ErrClientParams');
        $has_friend = false;
        $friend_list = \App\Http\Models\User::myFriends($uid);
        foreach ($friend_list as $f) {
            if ($f['uid'] == $fuid) {
                $has_friend = true;
                break;
            }
        }
        if (!$has_friend) return $this->throwError('ErrNoThisFriend');
        $is_help = true;
        // 助力每日限制
        if(Redis::SISMEMBER('FriendHelp:'.date('Ymd').':'.$fuid, $uid)) {
            $is_help = false;
        }
        if(Redis::SCARD('FriendHelp:'.date('Ymd').':'.$fuid) >= config('game.cfg.FriendHelpMaxTimes') ) {
            $is_help = false;
        }

        $finfo = DB::table('users')->where('id', $fuid)->first();
        if (!isset($finfo['duckId'])) return $this->throwError('ErrFriendDataError');

        $duck_info = DB::table('ducks')->where('id', $finfo['duckId'])->first();
        if (!isset($duck_info['id'])) return $this->throwError('ErrFriendDataError');

        // 刷新好友鸭子数据
        User::refreshFodder($fuid, $duck_info, false);

        // 不在家不可助力
        if($duck_info['status'] == config('game.cfg.DuckStatus.Steal')) {
            $is_help = false;
        }
        // 已吃完, 不可助力
        if($duck_info['leftFodder'] <= 0 && $duck_info['lastFeedTime'] <= 0) {
            $is_help = false;
        }
        return $this->result([
            'isHelp' => $is_help,
        ]);
    }
}
